package com.wx.house.manager.api.contract.service.impl;

import com.wx.house.manager.api.contract.service.CContractService;
import com.wx.house.common.exception.BusinessException;
import com.wx.house.common.util.IDUtils;
import com.wx.house.common.util.StringUtil;
import com.wx.house.core.mapper.building.BuildingRoomMapper;
import com.wx.house.core.mapper.contract.CContractDetailMapper;
import com.wx.house.core.mapper.contract.CContractMapper;
import com.wx.house.core.mapper.expenses.EAutoCreatePlanMapper;
import com.wx.house.core.mapper.expenses.ECollectFeesMapper;
import com.wx.house.core.mapper.expenses.ECostDetailMapper;
import com.wx.house.core.mapper.expenses.ECostMapper;
import com.wx.house.core.mapper.fileupload.AttaUploadMapper;
import com.wx.house.core.mapper.tenant.TUserMapper;
import com.wx.house.core.pojo.base.UserInfo;
import com.wx.house.core.pojo.bo.CContractBo;
import com.wx.house.core.pojo.dto.contract.InsertContractDto;
import com.wx.house.core.pojo.po.*;
import com.wx.house.core.pojo.po.building.BuildingRoom;
import com.wx.house.core.pojo.state.*;
import com.wx.house.core.pojo.vo.CcontractBuildVo;
import com.wx.house.core.pojo.vo.ContractBaseVo;
import com.wx.house.core.pojo.vo.ContractVo;
import lombok.RequiredArgsConstructor;

import org.apache.commons.lang3.ObjectUtils;
import org.checkerframework.common.value.qual.IntVal;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;

import javax.annotation.Resource;

@Service
@RequiredArgsConstructor
public class CContractServiceImpl extends ServiceImpl<CContractMapper, CContract> implements CContractService {
private final CContractMapper cContractMapper;
private final CContractDetailMapper cContractDetailMapper;
private final BuildingRoomMapper buildingRoomMapper;
private final AttaUploadMapper attaUploadMapper;
private final ECostMapper eCostMapper;
private final ECostDetailMapper eCostDetailMapper;
private final TUserMapper tUserMapper;
@Override
public List<ContractVo> selectAllContract(String mAccId, String contractKeyword, String tenantKeyword,Integer state,Integer daysTime) {
	return cContractMapper.selectAllContract(mAccId, contractKeyword, tenantKeyword,state,daysTime);
}

@Override
public void insertContract(InsertContractDto insertContractDto, UserInfo userInfo) {
	//时间
	 Calendar calendar = Calendar.getInstance();
     calendar.setTime(insertContractDto.getStartTime());
     SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
     //
     ContractDetail contractDetail = new ContractDetail();
     if(StringUtil.isEmpty(insertContractDto.getRemarks())) {
    	 insertContractDto.setRemarks("请输入备注");
     }
	//判断预付费是否与付费类型真确
	if(insertContractDto.getRentType()==7) {
		int c=(insertContractDto.getPrepayment().divide(insertContractDto.getChargeMoney())).intValue();
		calendar.add(Calendar.MONTH, c); 
		BigDecimal a7=insertContractDto.getPrepayment().divide(insertContractDto.getChargeMoney()).multiply(insertContractDto.getChargeMoney());
		contractDetail.setNextChargeTime(calendar.getTime());
		if(insertContractDto.getPrepayment().compareTo(a7)!=0) {
			throw new BusinessException("月付费，金额不对");
		}
	}
	if(insertContractDto.getRentType()==8) {
		int c=(insertContractDto.getPrepayment().divide(insertContractDto.getChargeMoney())).intValue();
		calendar.add(Calendar.MONTH, c*3); 
		contractDetail.setNextChargeTime(calendar.getTime());
		BigDecimal a8=insertContractDto.getPrepayment().divide(insertContractDto.getChargeMoney()).multiply(insertContractDto.getChargeMoney());
		if(insertContractDto.getPrepayment().compareTo(a8)!=0) {
			throw new BusinessException("季度付费，金额不对");
		}
	}
	if(insertContractDto.getRentType()==9) {
		int c=(insertContractDto.getPrepayment().divide(insertContractDto.getChargeMoney())).intValue();
		calendar.add(Calendar.MONTH, c*6); 
		contractDetail.setNextChargeTime(calendar.getTime());
		BigDecimal a9=insertContractDto.getPrepayment().divide(insertContractDto.getChargeMoney()).multiply(insertContractDto.getChargeMoney());
		if(insertContractDto.getPrepayment().compareTo(a9)!=0) {
			throw new BusinessException("半年付费，金额不对");
		}
	}
	if(insertContractDto.getRentType()==10) {
		int c=(insertContractDto.getPrepayment().divide(insertContractDto.getChargeMoney())).intValue();
		contractDetail.setNextChargeTime(calendar.getTime());
		System.out.println("时间:"+calendar.getTime());
		BigDecimal a10=insertContractDto.getPrepayment().divide(insertContractDto.getChargeMoney()).multiply(insertContractDto.getChargeMoney());
		if(insertContractDto.getPrepayment().compareTo(a10)!=0) {
			throw new BusinessException("年付费，金额不对");
		}
	}
	//合同信息是否重复
	if (cContractMapper.selectByContrName(insertContractDto.getContrName()) != null)
		throw new BusinessException("合同名字已经存在，请换更换其他名字试试");
	if (cContractMapper.selectByContrNumber(insertContractDto.getContrNumber()) != null)
		throw new BusinessException("合同编号已经存在，请换更换其他名字试试");
	
	//房间是否已被出租
	BuildingRoom buildingRoom = buildingRoomMapper.selectById(insertContractDto.getRoomId());
	if (buildingRoom == null) throw new BusinessException("未找到相应的出租房间");
	if (buildingRoom.getBuildType().equals(BuildHireEnum.HIRED.state))
		throw new BusinessException("该房间已被出租，请更换其他房间试试");
	Date entDate =new Date();
	String cContractId = IDUtils.createUUId();
	CContract cContract = new CContract();
	cContract.setId(cContractId);
	cContract.setContrNumber(insertContractDto.getContrNumber());
	cContract.setContrName(insertContractDto.getContrName());
	cContract.setRoomId(insertContractDto.getRoomId());
	cContract.setTenantName(insertContractDto.getTenantName());
	cContract.setTenantPhone(insertContractDto.getTenantPhone());
	cContract.setTenantCertificates(insertContractDto.getTenantCertificates());
	cContract.setTenantCertiNumber(insertContractDto.getTenantCertiNumber());
	cContract.setRemarks(insertContractDto.getRemarks());
	cContract.setAddTime(new Date());
	cContract.setOperation(userInfo.getRealName());
	cContract.setOperationTime(new Date());
	if(insertContractDto.getEndTime().before(entDate)) {
		cContract.setLogicalState(LogicalDeleteEnum.EXPIRE.state);
	}else {
		cContract.setLogicalState(LogicalDeleteEnum.NORMAL.state);
	}
	cContract.setMAccId(userInfo.getMAccId());
	
	contractDetail.setId(IDUtils.createUUId());
	contractDetail.setContractId(cContractId);
	contractDetail.setContractTerm(insertContractDto.getContractTerm());
	contractDetail.setContractTermUnit(insertContractDto.getContractTermUnit());
	contractDetail.setStartTime(insertContractDto.getStartTime());
	contractDetail.setEndTime(insertContractDto.getEndTime());
	contractDetail.setDeposit(insertContractDto.getDeposit());
	contractDetail.setRentType(insertContractDto.getRentType());
	contractDetail.setPrepayment(insertContractDto.getPrepayment());
	contractDetail.setChargeMoney(insertContractDto.getChargeMoney());
	contractDetail.setPropertyManager(insertContractDto.getPropertyManager());
	contractDetail.setEndWater(insertContractDto.getEndWater());
	contractDetail.setEndElectric(insertContractDto.getEndElectric());
	contractDetail.setEndGas(insertContractDto.getEndGas());
	
	if (cContractMapper.insertSelective(cContract) != 1) {
		throw new BusinessException("合同新增失败,请联系管理员");
	}
	if (cContractDetailMapper.insertSelective(contractDetail) != 1) {
		throw new BusinessException("合同新增失败,请联系管理员");
	}
	
	TUser selectPhone = tUserMapper.selectPhone(insertContractDto.getTenantPhone());
	if(!ObjectUtils.isEmpty(selectPhone)) {
		if(tUserMapper.updateTuserMaccId(userInfo.getMAccId(), selectPhone.getId())!=1) {
			throw new BusinessException("无房东用户更新房东失败");
		}
	}else {
		throw new BusinessException("用户不存在，合同添加失败");
	}
	
	if (buildingRoomMapper.hireBuildingRoom(
			BuildHireEnum.HIRED.state,
			insertContractDto.getRoomId(),
			insertContractDto.getEndWater(),
			insertContractDto.getEndElectric(),
			insertContractDto.getEndGas()) != 1) 
	{
		throw new BusinessException("房屋出租失败,请联系管理员");
	}
	if (insertContractDto.getContractFileIdList().size() >= 1) {
		if (attaUploadMapper.updateResourceIdByIdIn(cContractId, insertContractDto.getContractFileIdList()) != insertContractDto.getContractFileIdList().size()) {
			throw new BusinessException("租户新增绑定附件异常");
		}
	} else throw new BusinessException("还没有上传证件图片信息");
	//处理生成计划和生成收费记录
	this.createChargePlan(insertContractDto, userInfo, cContract, contractDetail);
}

@Override
public void createChargePlan(InsertContractDto insertContractDto, UserInfo userInfo, CContract cContract, ContractDetail contractDetail) {
	//7[月付] 8[季付] 9[半年付] 10[年付
	SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");  
	String dateNow = sdf.format(contractDetail.getStartTime());
	List<ECostDetail> costDetails=new ArrayList<>();
	
	//创建保证金待处理费用
	String ECostId=	null;
	String eCost1Id=String.valueOf(IDUtils.genItemId(16));
	
	ECost eCost1=new ECost();
	eCost1.setId(eCost1Id);
	eCost1.setContrId(cContract.getId());
	eCost1.setContrNumber(cContract.getContrNumber());
	eCost1.setContrName(cContract.getContrName());
	eCost1.setCreationTime(new Date());
	eCost1.setChargeMonth(dateNow);
	eCost1.setMAccId(userInfo.getMAccId());
	eCost1.setCostType(0);
	eCost1.setPayTypes("0");
	eCost1.setTotal(contractDetail.getDeposit());
	
	if(eCostMapper.insert(eCost1)!=1) {
		throw new BusinessException("添加保证金待处理费用失败");
	}else {
	 ECostId=eCost1Id;
	}
	
	//创建房租待处理费用
	String ECostIds=null;
	String eCost2Id=String.valueOf(IDUtils.genItemId(16));
	
	ECost eCost2=new ECost();
	eCost2.setId(eCost2Id);
	eCost2.setContrId(cContract.getId());
	eCost2.setContrNumber(cContract.getContrNumber());
	eCost2.setContrName(cContract.getContrName());
	eCost2.setCreationTime(new Date());
	eCost2.setChargeMonth(dateNow);
	eCost2.setMAccId(userInfo.getMAccId());
	eCost2.setCostType(0);
	eCost2.setPayTypes("1");
	eCost2.setTotal(contractDetail.getPrepayment());
	
	if(eCostMapper.insert(eCost2)!=1) {
		throw new BusinessException("添加房租待处理费用失败");
	}else {
		ECostIds=eCost2Id;
	}
	
	//创建待处理费用详情
	//保证金
	ECostDetail detail = ECostDetail.builder().creationTime(new Date()).netMoney(new BigDecimal(0.00))
			.costState(0).build();
	detail.setChargeType(0);
	detail.setReceiveMoney(contractDetail.getDeposit());
	detail.setId(String.valueOf(IDUtils.genItemId(16)));
	detail.setECostId(ECostId);
	costDetails.add(detail);
	//房租
	ECostDetail detail1 = ECostDetail.builder().creationTime(new Date()).netMoney(new BigDecimal(0.00))
			.costState(0).build();
	detail1.setChargeType(1);
	detail1.setReceiveMoney(contractDetail.getPrepayment());
	detail1.setId(String.valueOf(IDUtils.genItemId(16)));
	detail1.setECostId(ECostIds);
	costDetails.add(detail1);
	try {
		for (int i = 0; i < costDetails.size(); i++) {
			System.out.println("------"+costDetails.get(i));
			eCostDetailMapper.insert(costDetails.get(i));
		}
	} catch (Exception e) {
		throw new BusinessException("添加待处理费用详细失败");
	}
}

@Override
public void expenseCounter(String tenantPhone) {
}

@Override
public void deleteContract(String id) {
	buildingRoomMapper.resumeBuildingRoomByContractId(id);
	CContract cContract = new CContract();
	cContract.setId(id);
	cContract.setLogicalState(1);
	cContractMapper.updateById(cContract);
}

private ECollectFees buildECollectFees(String cContractId, BigDecimal a, Integer type, Integer depositPayType, String maccid) {
	ECollectFees eCollectFees = new ECollectFees();
	eCollectFees.setId(IDUtils.createUUId());
	eCollectFees.setSzType(ChargeDirectionEnum.CHARGE.getCode());
	eCollectFees.setFeesType(type);
	eCollectFees.setPaymentMethod(3);
	eCollectFees.setContractId(cContractId);
	eCollectFees.setFeeMonth(new SimpleDateFormat("yyyy-MM").format(new Date()));
	eCollectFees.setReceivable(a);
	eCollectFees.setActual(a);
	eCollectFees.setPaymentMethod(depositPayType);
	eCollectFees.setCreateTime(new Date());
	eCollectFees.setChargeTime(new Date());
	eCollectFees.setMAccId(maccid);
	return eCollectFees;
}


@Override
public List<CcontractBuildVo> selectNumber(String tenantKeyword) {
	return cContractMapper.selectNumber(tenantKeyword);
}

@Override
public List<CContractBo> selectByMAccId(String mAccId) {
	return cContractMapper.selectByMAccId(mAccId);
}

@Override
public void validContractId(String id) {
		CContract cContract = cContractMapper.selectByContrNumber(id);
		if (cContract != null) {
			throw new BusinessException("合同编号已经存在");
		}
}

@Override
public ContractBaseVo selectIdBase(String contrNumber) {
	return cContractMapper.selectIdBase(contrNumber);
}

@Override
public CContract selectContractId(String contractId) {
	return cContractMapper.selectById(contractId);
}

@Override
public void updateFile(String contractId) {
	BuildingRoom buildingRoom=buildingRoomMapper.selectContrIdberRoom(contractId);
	if(buildingRoomMapper.updateRoombuildType(buildingRoom.getId(), String.valueOf(0)) !=1 ) {
		throw new BusinessException("房间状态改为待出租失败");
	}
	if (cContractMapper.updateFile(contractId) != 1) {
		throw new BusinessException("合同归档失败");
	}
}

}